package com.sz.controller;

import com.alibaba.fastjson.JSON;
import com.codingapi.txlcn.tc.annotation.DTXPropagation;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.sz.mapper.TDealMapper;
import com.sz.model.Result;
import com.sz.model.TDeal;
import com.sz.model.TDealParticulars;
import com.sz.redission.DistributedLocker;
import com.sz.service.IBankCareService;
import com.sz.service.IDealParticularsService;
import com.sz.service.RegTranjFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/transfer")
public class TransferController {

    @Autowired
    private IDealParticularsService iDealParticularsService;

    @Autowired
    private TDealMapper tDealMapper;

    @Autowired
    private IBankCareService iBankCareService;


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private DistributedLocker distributedLocker;

    public final static String REDISSON_KEY = "redisson_key";

    //转账业务
    @LcnTransaction(propagation = DTXPropagation.REQUIRED)//分布式事务-调用者
    //propagation = DTXPropagation.REQUIRED：当前没有分布式事务，就创建。当前有分布式事务，就加入--默认
    //propagation = DTXPropagation.SUPPORTS：当前没有分布式事务，非分布式事务运行。当前有分布式事务，就加入

    @Transactional(rollbackFor=Exception.class)//本地事务
    @RequestMapping(value = "/transfer",method = RequestMethod.POST)
    public Result getInsertSealP(@RequestBody TDealParticulars tDealParticulars){
        Result result=null;
        System.out.println("dealp = " + tDealParticulars);

        int transfer=0;
        String sixstr=tDealParticulars.getPayeeAccount().substring(0,6);
        //查询原余额
        Long aLong = iBankCareService.selectMoney(tDealParticulars.getPayerAccount());
        Long aLong2 = iBankCareService.selectMoney(tDealParticulars.getPayeeAccount());
        tDealParticulars.setPayerAmount(aLong);
        tDealParticulars.setPayeeAmount(aLong2);

        //分布式锁
        try{
            System.out.println("=============获取转账请求开始============"+Thread.currentThread().getName());


            boolean lock = distributedLocker.tryLock(REDISSON_KEY, TimeUnit.SECONDS, 5L, 6L);
            if (lock) {
                System.out.println("开始转账"+Thread.currentThread().getName());
                //TODO 获取到锁执行转账操作
                Thread.sleep(1000);
                if(sixstr.equals("202107")){
                    //同行    //汇款人账户     //对方账户     //转账金额
                    transfer = iBankCareService.Transfer(tDealParticulars.getPayerAccount(), tDealParticulars.getPayeeAccount(),  tDealParticulars.getTradingAmount());
                    //System.out.println(1/0);
                }else{
                    //跨行    //汇款人账户     //对方其他银行账户     //转账金额
                    transfer = iBankCareService.OtherBankTransfer(tDealParticulars.getPayerAccount(), tDealParticulars.getPayeeAccount(),  tDealParticulars.getTradingAmount());
                }
                System.out.println("======转账完成======" + Thread.currentThread().getName());
            }
        }catch (Exception e){
            System.out.println("错误信息：{}"+e.toString());
            System.out.println("转账观察出现异常"+Thread.currentThread().getName());
        }
        //根据转账返回值判断成功
        if(transfer!=2){
            result=new Result(301,"转账失败，存在风险或额度不足");
            tDealParticulars.setTrading(new Long(0));
        }else {
            //System.out.println("aLong = " + aLong);
            //System.out.println("aLong2 = " + aLong2);
            result = new Result(200, "转账成功");
            tDealParticulars.setCurrency("人民币");
            tDealParticulars.setTrading(new Long(1));
            tDealParticulars.setTransaction("系统");
            tDealParticulars.setServiceCharge(new Long(2));

        }

        System.out.println("交易记录详情-tDealParticulars = " + tDealParticulars.toString());
        //返回自增主键,
        iDealParticularsService.insertDealP(tDealParticulars);
        //System.out.println("记录编号"+tDealParticulars.getPkPId());

        //添加交易记录
        TDeal tDeal = new TDeal(tDealParticulars.getPkPId(), tDealParticulars.getPayerName(), tDealParticulars.getPayerAccount(), tDealParticulars.getTradingAmount(), 0, new Date());
        TDeal tDeal2 = new TDeal(tDealParticulars.getPkPId(), tDealParticulars.getPayeeName(), tDealParticulars.getPayeeAccount(), tDealParticulars.getTradingAmount(), 1, new Date());

        int i = tDealMapper.insertDeal(tDeal);
        i += tDealMapper.insertDeal(tDeal2);
        System.out.println("i = " + i);

        //获取账户最后判断是否正常转账
        TDealParticulars tdealPByAccount = iDealParticularsService.getTdealPByAccount(tDealParticulars.getPayerAccount(), tDealParticulars.getPayeeAccount());
        Long payeracc = iBankCareService.selectMoney(tDealParticulars.getPayerAccount());
        Long payeeacc = iBankCareService.selectMoney(tDealParticulars.getPayeeAccount());
        //未转账金额
        Long tdealP =tdealPByAccount.getPayeeAmount()+tDealParticulars.getPayerAmount();
        //已经转账后
        Long payamount=payeeacc+payeracc;
        //System.out.println("tdealP = " + tdealP);
        //System.out.println("payamount = " + payamount);

        if(tdealP<=payamount+50){
            System.out.println("转账正常");
            String phoneByAccount = iBankCareService.getPhoneByAccount(tDealParticulars.getPayeeAccount());

            //发送短信
            //SMSCode.sendSMS(phoneByAccount);

        }else{
            System.out.println(1/0);
            result=new Result(501,"系统出现严重异常，请检查");
        }

        return result;
    }

    //延期到账
    @RequestMapping(value = "/redis",method = RequestMethod.POST)
    public Result setRedisTransfer(@RequestBody TDealParticulars tDealParticulars){
        Result result=null;
        String s = JSON.toJSONString(tDealParticulars);

        int time=60*60*2;
        //stringRedisTemplate.opsForValue().set("tDealParticulars",s,time, TimeUnit.SECONDS);
        stringRedisTemplate.opsForValue().set("tDealParticulars",s);

        result=new Result(200,"已接收到普通转账请求，请等待2个小时注意到账短信提醒！");

        return result;
    }

    //撤销转账
    @RequestMapping(value = "/annul",method = RequestMethod.POST)
    public Result AnnulTransfer(@RequestBody String payerAccount){
        System.out.println("撤销账户payerAccount = " + payerAccount);
        Result result=null;
        String s = stringRedisTemplate.opsForValue().get("tDealParticulars");

        if(s!=null&&s!=""){
            TDealParticulars tDealParticulars = JSON.parseObject(s, TDealParticulars.class);

            if(payerAccount.equals(tDealParticulars.getPayerAccount())){
                stringRedisTemplate.delete("tDealParticulars");
                result=new Result(201,"撤销成功!!");
            }else{
                result=new Result(301,"转账记录不存在或已经到账");
            }
        }else{
            result=new Result(302,"转账记录不存在或已经到账");
        }

        return result;
    }

    //分布式转账
    @RequestMapping(value = "/regtran",method = RequestMethod.POST)
    public Result RegTransfer(String payerAccount,Long tradingAmount){

        System.out.println("---------"+payerAccount);
        Result result=null;
        int i = iBankCareService.RegTranBank(payerAccount, tradingAmount);

        if(i==1){
            result=new Result(200,"转账成功");
        }else{
            result=new Result(301,"转账失败");
        }

        return result;
    }


}
